package com.hhkj.admin.student.service.extend.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hhkj.admin.course.common.cont.CourseConst;
import com.hhkj.admin.course.domain.Course;
import com.hhkj.admin.student.common.cont.StudentConst;
import com.hhkj.admin.student.domain.Student;
import com.hhkj.admin.student.model.dopo.StudentDo;
import com.hhkj.admin.student.model.dopo.StudentPo;
import com.hhkj.admin.student.model.req.StudentReq;
import com.hhkj.admin.student.service.base.StudentCourseService;
import com.hhkj.admin.student.service.base.StudentService;
import com.hhkj.admin.student.service.extend.StudentExtendService;
import com.hhkj.admin.train.model.dopo.TrainPo;
import com.hhkj.api.train.common.cont.ApiTrainConst;
import com.ruoyi.common.base.biz.service.extend.BaseExtendServiceImpl;
import com.ruoyi.common.constant.SysUserCodeConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 学员管理ServiceExtend接口
 *
 * @author ruoyi
 * @since 2023-06-08
 */
@Service
public class StudentExtendServiceImpl
        extends BaseExtendServiceImpl<Student, StudentDo, StudentPo, StudentService>
        implements StudentExtendService {
    @Autowired
    private StudentService studentService;
    @Autowired
    private StudentCourseService studentCourseService;

    @Override
    public Student getByIdCard(String idCard) {
        LambdaQueryWrapper<Student> query = new LambdaQueryWrapper<>();
        query.eq(Student::getIdCard, idCard);
        return this.getService().getOne(query, false);
    }

    @Override
    public Student getByIdCardAndCreateBy(String idCard, Long createBy) {
        LambdaQueryWrapper<Student> query = new LambdaQueryWrapper<>();
        query.eq(Student::getIdCard, idCard)
                .eq(Student::getCreateBy, createBy);
        return this.getService().getOne(query, false);
    }

    /**
     * 查询学员信息列表
     *
     * @param studentReq 学员信息
     * @return 学员信息集合
     */
    @Override
    public List<StudentPo> selectStudentList(StudentReq studentReq) {
        //补充条件
        applyCondition(studentReq);
        List<StudentPo> students = studentCourseService.selectStudentRelevancyList(studentReq);
        //查询后处理
        afterSelectStudent(students);
        //关联最近练习时间
        applyPracticeInfo(students);
        return students;
    }

    /**
     * 查询后处理
     *
     * @param studentPos 查询出来的学员信息
     */
    private void afterSelectStudent(List<StudentPo> studentPos) {
        //2023年6月15日 管理员登录才显示题库类型
        if (!SysUser.isAdminTypeCode(SecurityUtils.getTypeCode())) {
            studentPos.forEach(o -> {
                o.setCourseBankTypeId(null);
                o.setCourseBankTypeName(null);
            });
        }
    }

    /**
     * 补充查询条件
     *
     * @param studentReq 前台传参
     */
    private void applyCondition(StudentReq studentReq) {
        if (!SysUser.isAdminTypeCode(SecurityUtils.getTypeCode())) {
            if (SysUserCodeConstants.UserCode.ENTERPRISE.getCode().equals(SecurityUtils.getTypeCode())) {
                //企业只看见已通过
                studentReq.setEntId(SecurityUtils.getUserId());
                studentReq.setStatus(StudentConst.AuditCode.STATUS_PASS.getCode());
            } else {
                //机构看见自己导入的
                studentReq.setInsId(SecurityUtils.getUserId());
            }
        }
    }

    /**
     * 关联学员最近一次练习
     *
     * @param studentPos 传参
     */
    private void applyPracticeInfo(List<StudentPo> studentPos) {
        if (studentPos.size() > 0) {
            //查询学员id汇总，并查询练习记录
            List<Long> studentIds = studentPos.stream().map(StudentPo::getId).collect(Collectors.toList());
            List<TrainPo> trainPos = studentService.selectTrainByIdList(ApiTrainConst.TypeCode.PRACTISE.getCode(), studentIds);
            if (trainPos != null && trainPos.size() > 0) {
                for (StudentPo studentPo1 : studentPos) {
                    //过滤出该学员的练习记录并排序获取最新一条
                    List<TrainPo> lastTrain = trainPos
                            .stream()
                            .filter(o -> o.getStudentId().equals(studentPo1.getId()) && o.getCourseId().equals(studentPo1.getCourseId()))
                            .sorted(Comparator.comparing(TrainPo::getSubmitTime).reversed())
                            .limit(1)
                            .collect(Collectors.toList());
                    if (lastTrain.size() > 0) {
                        studentPo1.setLastPracticeTime(lastTrain.get(0).getSubmitTime());
                    }
                }
            }
        }
    }

    /**
     * 课程结构名称设置
     *
     * @param course        课程
     * @param courseMapById 课程 id map
     * @param parentId      上级id
     */
    private void setStructureName(Course course, Map<Long, Course> courseMapById, Long parentId) {
        if (CourseConst.ROOT_PARENT_ID.equals(course.getParentId())) {
            course.setStructureName(course.getName());
            return;
        }
        if (StrUtil.isBlank(course.getStructureName())) {
            course.setStructureName(course.getName());
        }
        if (courseMapById.containsKey(parentId)) {
            Course parentCourse = courseMapById.get(parentId);
            if (CourseConst.ROOT_PARENT_ID.equals(parentCourse.getParentId())) {
                course.setStructureName(parentCourse.getName() + StrUtil.SLASH + course.getStructureName());
                return;
            }
            course.setStructureName(parentCourse.getName() + StrUtil.SLASH + course.getStructureName());
            setStructureName(course, courseMapById, parentCourse.getParentId());
        }
    }
}
